! function(win) {

	var ajax = function(opts) {

		var xhr = function() {
			var _xhr = null;
			try {
				_xhr = new XMLHttpRequest();
			} catch(e) {
				var IEXHRVers = ["Msxml3.XMLHTTP", "Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
				for(var i = 0, len = IEXHRVers.length; i < len; i++) {
					try {
						_xhr = new ActiveXObject(IEXHRVers[i]);
					} catch(e) {
						continue;
					}
				}
			}
			return _xhr;
		}();

		var init = function(opts) {
			var opt = tool.optionExtend({
				//'waitloading': true,
				'type': 'get',
				'url': '',
				'data': {},
				//'dataType': 'json', // json || jsonp || xml || html || script || text
				//'jsonp': 'callback',
				//'jsonpCallback': 'jsonpCallback',
				'async': true,
				'timeout': 5000,
				'header': {},
				'beforeSend': function() {},
				'complete': function(XMLHttpRequest, textStatus) {}
			}, opts);

			var data_opt = '';
			if(opt.data instanceof Object) {
				var data_arrs = [];
				for(var i in opt.data) {
					data_arrs.push(i + '=' + opt.data[i]);
				}
				data_opt = data_arrs.join('&');
			} else if(typeof opt.data == 'string') {
				data_opt = opt.data;
			}
			tool.p('data_opt', data_opt);

			/*var ajaxurl = {
				'protocol': 'http://',
				//'host': 'rea.51dojob.com',
				'host': 'rea.local',
				'pathname': 'api',
				'search': opt.url
			};
			data_url = ajaxurl.protocol + ajaxurl.host + '/' + ajaxurl.pathname + '?' + ajaxurl.search;*/

			var readystatechange = function() {
				switch(xhr.readyState) {
					case 0:
						// 0(UNSENT):未初始化。尚未调用open()方法
						break;
					case 1:
						// 1(OPENED):启动。已经调用open()方法，但尚未调用send()方法
						break;
					case 2:
						// 2(HEADERS_RECEIVED):发送。己经调用send()方法，且接收到头信息
						break;
					case 3:
						// 3(LOADING):接收。已经接收到部分响应主体信息
						break;
					case 4:
						// 4(DONE):完成。已经接收到全部响应数据，而且已经可以在客户端使用了
						tool.p('xhr', xhr);
						var result = {
							'status': xhr.status
						};
						if(xhr.responseText !== '' && xhr.status != 500) {
							var response = JSON.parse(xhr.responseText);
							if(xhr.status >= 200 && xhr.status < 300) {
								result['data'] = response;
							} else if(xhr.status >= 400) {
								result['error'] = response.error;
							}
						} else {
							result['data'] = xhr.responseText;
						}
						opt.complete(result);
						break;
					default:
						// abnormal
						break;
				}
			};

			var data_url = opt.url;
			if(opt.type === 'get' && data_opt !== '') {
				if((/\?/gi).test(opt.url)) {
					data_url += '&' + data_opt;
				} else {
					data_url += '?' + data_opt;
				}
			}
			tool.p('data_url', data_url);

			xhr.open(opt.type, data_url, opt.async);
			if(opt.async === true) {
				// 异步请求
				xhr.onreadystatechange = readystatechange;
			}
			if(opt.type == 'post' || opt.type == 'put' || opt.type == 'delete') {
				// post请求
				xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
				//xhr.setRequestHeader("Content-Type","multipart/form-data");
				//xhr.setRequestHeader("Content-Type","text/plain");
			}

			// header
			for(var i in opt.header) {
				xhr.setRequestHeader(i, opt.header[i]);
			}

			xhr.send(opt.type === 'get' ? null : data_opt);
			if(opt.async === true) {
				// 同步请求
				readystatechange();
			}
		}

		this.upload = function(url, form, fn_opt) {
			xhr.open('POST', url, true);
			xhr.onload = function() {
				var result = {
					'status': xhr.status
				};
				if(xhr.responseText !== '') {
					var response = JSON.parse(xhr.responseText);
					if(xhr.status >= 200 && xhr.status < 300) {
						result['data'] = response;
					} else if(xhr.status >= 400) {
						result['error'] = response.error;
					}
				} else {
					result['data'] = xhr.responseText;
				}
				fn_opt.onload && fn_opt.onload(result);
			}
			xhr.onerror = function() {
				fn_opt.onerror && fn_opt.onerror(xhr);
			}
			//xhr.onload = fn_opt.load; //请求完成
			//xhr.onerror = fn_opt.error; //请求失败
			//xhr.upload.onprogress = fn_opt.progress; //上传进度调用方法实现
			//xhr.upload.onloadstart = fn_opt.loadstart;//上传开始执行方法
			xhr.send(form);
		}

		this.get = function() {
			var url = arguments[0] || '';
			if(url == '') return;
			var data = (arguments[1] && typeof arguments[1] == 'object') ? arguments[1] : {};
			var fn = (arguments[1] && typeof arguments[1] == 'function') ? arguments[1] : (arguments[2] || function() {});
			init({
				'type': 'get',
				'url': url,
				'data': data,
				'complete': fn
			});
		}

		this.post = function() {
			var url = arguments[0] || '';
			if(url == '') return;
			var data = (arguments[1] && typeof arguments[1] == 'object') ? arguments[1] : {};
			var fn = (arguments[1] && typeof arguments[1] == 'function') ? arguments[1] : (arguments[2] || function() {});
			init({
				'type': 'post',
				'url': url,
				'data': data,
				'complete': fn
			});
		}

		this.put = function() {
			var url = arguments[0] || '';
			if(url == '') return;
			var data = (arguments[1] && typeof arguments[1] == 'object') ? arguments[1] : {};
			var fn = (arguments[1] && typeof arguments[1] == 'function') ? arguments[1] : (arguments[2] || function() {});
			init({
				'type': 'put',
				'url': url,
				'data': data,
				'complete': fn
			});
		}

		this.del = function() {
			var url = arguments[0] || '';
			if(url == '') return;
			var data = (arguments[1] && typeof arguments[1] == 'object') ? arguments[1] : {};
			var fn = (arguments[1] && typeof arguments[1] == 'function') ? arguments[1] : (arguments[2] || function() {});
			init({
				'type': 'delete',
				'url': url,
				'data': data,
				'complete': fn
			});
		}

		if(typeof opts == 'object') {
			init(opts);
		} else {
			return this;
		}
	}

	win.ajax = ajax;
}(window);